<?php

namespace App\Http\Controllers;

use App\BO\CartItem\CreateCartItemInfo;
use App\BO\Coupon\CouponProductSkuCheck\CheckResultWrapper;
use App\Entities\CartItemEntity;
use App\Entities\UserAddressEntity;
use App\Http\Requests\StoreCartItemRequest;
use App\ServicesNew\CartService;
use App\ServicesNew\UserAddressService;
use App\ServicesNew\UserBalanceService;
use App\Utils\GenObjFromRequestUtil;
use App\Utils\MoneyFormatUtil;
use App\Utils\Tool;
use App\VO\Cart\CartIndexVO;
use App\VO\Cart\MetaInfo\CartFactory;
use Illuminate\Http\Request;

/**
 * 购物车
 * Class CartController
 * @package App\Http\Controllers
 */
class CartController extends BaseController
{
    /**
     * @var CartService
     */
    private $cartService;

    public function __construct(CartService $cartService)
    {
        $this->cartService = $cartService;
    }

    /**
     * @api {get} /cart 购物车页面
     * @apiGroup Cart
     *
     * @apiParam {Number} [addressId]  地址ID
     */
    /**
     * @param Request $request
     * @param UserBalanceService $userBalanceService
     * @param UserAddressService $userAddressService
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function index(Request $request, UserBalanceService $userBalanceService, UserAddressService $userAddressService)
    {
        $userId = $this->getUserId();

        $cartItemEntity = $this->cartService->getCartItemEntityByUserId($userId);
        if (is_null($cartItemEntity)) {
            return $this->showJsonResult(500, '购物车数据为空');
        }

        $cartIndexVO = new CartIndexVO();
        $cartIndexVO->setAmount(MoneyFormatUtil::pennyToDollar($userBalanceService->getUseAbleAmountByUid($userId)));
        $cartIndexVO->setNum($cartItemEntity->getSquareMetre());
        $cartIndexVO->setProductSku(CartFactory::getProductSkuInfo($cartItemEntity));
        $this->setServiceDate($cartIndexVO, $cartItemEntity);
        $this->setCoupon($cartIndexVO, $cartItemEntity);

        $userAddressEntity = $this->getUserAddress($userAddressService, $request);
        if ($userAddressEntity) {
            $cartIndexVO->setAddress(CartFactory::getUserAddressInfo($userAddressEntity));
        }

        return $this->successJsonResult($cartIndexVO);
    }

    /**
     * @param CartIndexVO $cartIndexVO
     * @param CartItemEntity $cartItemEntity
     */
    private function setServiceDate(CartIndexVO $cartIndexVO, CartItemEntity $cartItemEntity)
    {
        $cartIndexVO->setAssignDate($cartItemEntity->getAssignDate());
        $cartIndexVO->setAssignTime($cartItemEntity->getAssignTime());
        $cartIndexVO->setAssignTimeDes(Tool::periodCode2StrNew($cartItemEntity->getAssignTime(), true));
    }

    /**
     * @param UserAddressService $userAddressService
     * @param Request $request
     * @return UserAddressEntity|null
     */
    private function getUserAddress(UserAddressService $userAddressService, Request $request)
    {
        $userId = $this->getUserId();
        $cityId = $this->getUserLocationCityId();

        $addressId = $request->input('addressId') ?: 0;
        if ($addressId > 0) {
            $userAddressEntity = UserAddressEntity::find($addressId);
        } else {
            $userAddressEntity = $userAddressService->getSuitableUserAddress($userId, $cityId);
        }
        return $userAddressEntity;
    }

    private function setCoupon(CartIndexVO $cartIndexVO, CartItemEntity $cartItemEntity)
    {
        list($useAble, $unUseAble) = $this->cartService->useAbleGroupByCouponByCartItemEntity($cartItemEntity);
        $cartIndexVO->setUseAbleCoupons($this->format($useAble));
        $cartIndexVO->setUnUseAbleCoupons($this->format($unUseAble));
    }

    /**
     * @param CheckResultWrapper[] $wrappers
     * @return array
     */
    protected function format(array $wrappers)
    {
        $list = [];
        foreach ($wrappers as $wrapper) {
            $list[] = CartFactory::getCouponInfo($wrapper);
        }
        return $list;
    }

    /**
     * @api {post} /cart  添加加购物车
     * @apiGroup Cart
     *
     * @apiParam {Number} productSkuId  skuID
     * @apiParam {Number} num  购买数量
     * @apiParam {String} assignDate  下单日期，格式 2020-09-08
     * @apiParam {Number} assignTime  下单时间段
     */
    /**
     * @param StoreCartItemRequest $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function store(StoreCartItemRequest $request)
    {
        if (!$request->passValidate()) {  // 验证不通过
            return $this->showJsonResult(500, $request->getErrorMessage());
        }

        $userId = $this->getUserId();
        $cityId = $this->getUserLocationCityId();

        $productSkuEntity = $request->getProductSku();

        $createCartItemInfo = $this->getCreateCartItemInfoFromRequest($request);
        $createCartItemInfo->setProductId($productSkuEntity->getProductId());
        $createCartItemInfo->setProductSkuId($productSkuEntity->getId());
        $createCartItemInfo->setUserId($userId);
        $createCartItemInfo->setCityId($cityId);

        $this->cartService->createCartItem($createCartItemInfo);

        return $this->successJsonResult();
    }

    /**
     * @param Request $request
     * @return CreateCartItemInfo
     */
    private function getCreateCartItemInfoFromRequest(Request $request)
    {
        /** * @var CreateCartItemInfo $info */
        $info = GenObjFromRequestUtil::getObj(CreateCartItemInfo::class, $request);
        return $info;
    }
}
